class StrongKeyLite

  # Module included into {StrongKeyLite} with higher-level API actions.

  module API

    # Pings the service and returns information about its health. You must have
    # a user set for the @:ping@ API action.
    #
    # @return [Hash] A hash of service status information (see example).
    # @example Example response
    #   { :version => "1.0",
    #     :build => 40,
    #     :hostname => "demo.strongauth.com",
    #     :current_time => #<Time Thu Nov 11 18:52:45 PST 2010>,
    #     :up_since => #<Time Mon Sep 27 20:58:05 PDT 2010>,
    #     :well_known_pan => 1235711131719230,
    #     :encryptions_since_startup => 6,
    #     :encryptions_total => 17,
    #     :decryptions_since_startup => 9,
    #     :decryptions_total => 20,
    #     :deletions_since_startup => 0,
    #     :deletions_total => 0,
    #     :searches_since_startup => 1,
    #     :searches_total => 3,
    #     :batch_operations_since_startup => 0,
    #     :batch_operations_total => 0,
    #     :domain_id => 21
    #   }

    def ping
      msg = call(:ping)[:ping_response][:return]
      info = Hash.new
      msg.each_line do |line|
        if line =~ /^SKLES (.+?) \(Build (\d+)\)$/
          info[:version] = $1
          info[:build] = $2.to_i
        elsif line =~ /^Hostname: (.+?)$/ then
          info[:hostname] = $1
        elsif line =~ /^Current time: (.+?)$/ then
          info[:current_time] = Time.parse($1)
        elsif line =~ /^Up since: (.+?)$/ then
          info[:up_since] = Time.parse($1)
        elsif line =~ /^Well-known PAN: (\d+?)$/ then
          info[:well_known_pan] = $1.to_i
        elsif line =~ /^ENC: (\d+)\/(\d+)$/ then
          info[:encryptions_since_startup] = $1.to_i
          info[:encryptions_total] = $2.to_i
        elsif line =~ /^DEC: (\d+)\/(\d+)$/ then
          info[:decryptions_since_startup] = $1.to_i
          info[:decryptions_total] = $2.to_i
        elsif line =~ /^DEL: (\d+)\/(\d+)$/ then
          info[:deletions_since_startup] = $1.to_i
          info[:deletions_total] = $2.to_i
        elsif line =~ /^SRC: (\d+)\/(\d+)$/ then
          info[:searches_since_startup] = $1.to_i
          info[:searches_total] = $2.to_i
        elsif line =~ /^BAT: (\d+)\/(\d+)$/ then
          info[:batch_operations_since_startup] = $1.to_i
          info[:batch_operations_total] = $2.to_i
        elsif line =~ /SKLES Domain (\d+) is (.+?)$/ then
          info[:domain_id] = $1.to_i
        end
      end

      return info
    end

    # Stores a credit card number (or any other plain text content) to the vault
    # and returns an obscured token for later retrieval.
    #
    # @param [String] plaintext The text to encrypt and store.
    # @return [String] A token that can be used to {#decrypt} the text. The text
    #   is not derivable from the token without access to the StrongKey Lite
    #   server.

    def encrypt(plaintext)
      call(:encrypt, plaintext: plaintext)[:encrypt_response][:return]
    end

    # Retrieves a credit card number (or any other encrypted content) from the
    # vault using a ciphered token generated by a call to {#encrypt}.
    #
    # @param [String] token The ciphertext returned from @encrypt@.
    # @return [String] The text that was encrypted.

    def decrypt(token)
      call(:decrypt, token: token)[:decrypt_response][:return]
    end

    # Removes a credit card number (or any other encrypted content) from the
    # vault.
    #
    # @param [String] token The ciphertext returned from {#encrypt}.
    # @return [true, false] Whether or not the encrypted content was
    #   successfully deleted.

    def delete(token)
      call(:delete, token: token)[:delete_response][:return]
    end

    # Determines if a credit card number (or any other plain text content) is
    # stored in the vault. If so, returns its token.
    #
    # @param [String] plaintext The text to search for.
    # @return [String, nil] The token for the text, if stored, or @nil@ if no
    #   such text is stored in the vault.

    def search(plaintext)
      call(:search, plaintext: plaintext)[:search_response][:return]
    end
  end
end
